package user

import (
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"hosptial-record/api/base"
	"hosptial-record/forms"
	"hosptial-record/global"
	"hosptial-record/global/response"
	"hosptial-record/middlewares"
	"hosptial-record/model"
	"hosptial-record/strings"
	"net/http"
	"time"
)

// List 用户列表
func List(ctx *gin.Context) {
	var form forms.GetUserForm
	if err := ctx.ShouldBindQuery(&form); err != nil {
		base.HandleValidatorError(ctx, err)
		return
	}
	db := global.DB
	if form.Account != "" {
		db = db.Where("account = ?", form.Account)
	}
	if form.Name != "" {
		db = db.Where("name like ?", "%"+form.Name+"%")
	}
	var total int64
	var users []model.User
	res := db.
		Model(&model.User{}).
		Count(&total).
		Order("id desc").
		Scopes(base.Paginate(int(form.Page), int(form.PageSize))).
		Find(&users)
	if res.Error != nil {
		zap.S().Errorw("User [List] 获取用户列表失败", "msg", zap.Error(res.Error))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg:  "获取用户列表失败",
			Data: res.Error,
		})
		return
	}
	ctx.JSON(http.StatusOK, response.ListResponse{
		Msg: "获取成功",
		Data: response.ListData{
			Data:  users,
			Total: total,
		},
	})
}

func Detail(ctx *gin.Context) {
	id, err := base.GetID2Param(ctx)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, response.BaseResponse{
			Msg: "ID不合法",
		})
		return
	}
	var user model.User
	res := global.DB.First(&user, id)
	if res.Error != nil {
		zap.S().Errorw("User [Detail] 获取用户详情失败", "msg", zap.Error(res.Error))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg:  "获取失败",
			Data: res.Error,
		})
		return
	}
	ctx.JSON(http.StatusOK, response.BaseResponse{
		Msg:  "获取成功",
		Data: user,
	})
}

// OwnDetail 个人信息
func OwnDetail(ctx *gin.Context) {
	str, _ := ctx.Get(strings.UserId)
	id := int32(str.(uint))
	var user model.User
	user.ID = id
	res := global.DB.First(&user)
	if res.Error != nil {
		zap.S().Errorw("User [OwnDetail] 获取用户详情失败", "msg", zap.Error(res.Error))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg:  "获取失败",
			Data: res.Error,
		})
		return
	}
	ctx.JSON(http.StatusOK, response.BaseResponse{
		Msg:  "获取成功",
		Data: user,
	})
}

// Login 用户登录
func Login(ctx *gin.Context) {
	var form forms.LoginUserForm
	if err := ctx.ShouldBind(&form); err != nil {
		base.HandleValidatorError(ctx, err)
		return
	}
	var user model.User
	res := global.DB.Where("account = ?", form.Account).First(&user)
	if res.RowsAffected == 0 {
		ctx.JSON(http.StatusNotFound, response.BaseResponse{
			Msg: "账号不存在",
		})
		return
	}
	// 比较密码
	if form.Password != user.Password {
		ctx.JSON(http.StatusUnauthorized, response.BaseResponse{
			Msg: "密码错误",
		})
		return
	}
	// 是否被禁用
	if user.IsDisabled {
		ctx.JSON(http.StatusUnauthorized, response.BaseResponse{
			Msg: "账号被禁用",
		})
		return
	}
	// 验证通过返回token
	j := middlewares.NewJWT()
	// 创建自定义封装对象
	claims := model.CustomClaims{
		ID:         uint(user.ID),
		Name:       user.Name,
		Role:       uint(user.Role),
		IsDisabled: user.IsDisabled,
		StandardClaims: jwt.StandardClaims{
			NotBefore: time.Now().Unix(), // 签名生效时间
			// 默认一个月的有效期
			//ExpiresAt: time.Now().Add(time.Hour * 24 * 30).Unix(),
			// 签名者
			//Issuer: "alex",
		},
	}
	token, err := j.CreateToken(claims)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": "生成token失败",
		})
		zap.S().Errorf("User [Login] 生成token报错：%s", err.Error())
		return
	}
	// 返回结果
	ctx.JSON(http.StatusOK, response.BaseResponse{
		Msg:  "登录成功",
		Data: token,
	})
}

// Create 创建用户
func Create(ctx *gin.Context) {
	var form forms.UserForm
	if err := ctx.ShouldBind(&form); err != nil {
		base.HandleValidatorError(ctx, err)
		return
	}
	user := model.User{
		Name:       form.Name,
		Avatar:     form.Avatar,
		Account:    form.Account,
		Password:   form.Password,
		Role:       form.Role,
		IsDisabled: form.IsDisabled,
	}
	res := global.DB.Create(&user)
	if res.Error != nil {
		zap.S().Error("User [Create] 创建用户失败", zap.Error(res.Error))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg:  "创建失败",
			Data: res.Error,
		})
		return
	}
	ctx.JSON(http.StatusOK, response.BaseResponse{
		Msg: "创建成功",
	})
}

func AdminUpdate(ctx *gin.Context) {
	var form forms.AdminEditUserForm
	if err := ctx.ShouldBind(&form); err != nil {
		base.HandleValidatorError(ctx, err)
		return
	}
	user := model.User{
		Name:     form.Name,
		Avatar:   form.Avatar,
		Account:  form.Account,
		Password: form.Password,
		Role:     form.Role,
	}
	user.ID = form.ID
	res := global.DB.Updates(&user)
	if res.Error != nil {
		zap.S().Errorw("User [AdminUpdate] 修改用户信息失败", "msg", zap.Error(res.Error))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg:  "修改失败",
			Data: res.Error,
		})
		return
	}
	ctx.JSON(http.StatusOK, response.BaseResponse{
		Msg: "修改成功",
	})
}

// Update 修改用户信息
func Update(ctx *gin.Context) {
	var form forms.EditUserForm
	if err := ctx.ShouldBind(&form); err != nil {
		base.HandleValidatorError(ctx, err)
		return
	}
	id, _ := ctx.Get(strings.UserId)
	uid := int32(id.(uint))
	user := model.User{
		Name:   form.Name,
		Avatar: form.Avatar,
		Role:   form.Role,
	}
	user.ID = uid
	res := global.DB.Updates(&user)
	if res.Error != nil {
		zap.S().Errorw("User [Update] 修改用户信息失败", "msg", zap.Error(res.Error))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg:  "修改失败",
			Data: res.Error,
		})
		return
	}
	ctx.JSON(http.StatusOK, response.BaseResponse{
		Msg: "修改成功",
	})
}

// Delete 删除用户
func Delete(ctx *gin.Context) {
	id, err := base.GetID2Param(ctx)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, response.BaseResponse{
			Msg: "ID不合法",
		})
		return
	}
	res := global.DB.Delete(&model.User{}, id)
	if res.Error != nil {
		zap.S().Errorw("User [Delete] 删除用户失败", "msg", zap.Error(res.Error))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg:  "删除失败",
			Data: res.Error,
		})
	}
	ctx.JSON(http.StatusOK, response.BaseResponse{
		Msg: "删除成功",
	})
}

// Disable 禁用/启用用户
func Disable(ctx *gin.Context) {
	var form forms.DisableUserForm
	if err := ctx.ShouldBind(&form); err != nil {
		base.HandleValidatorError(ctx, err)
		return
	}
	var user model.User
	if form.Disable != nil {
		user.IsDisabled = *form.Disable
	}
	user.ID = form.ID
	res := global.DB.Select("IsDisabled").Updates(&user)
	if res.Error != nil {
		zap.S().Errorw("User [Disable] 禁用/启用用户失败", "msg", zap.Error(res.Error))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg:  "操作失败",
			Data: res.Error,
		})
		return
	}
	ctx.JSON(http.StatusOK, response.BaseResponse{
		Msg: "操作成功",
	})
}

func ChangePassword(ctx *gin.Context) {
	var form forms.ChangePwdForm
	if err := ctx.ShouldBind(&form); err != nil {
		base.HandleValidatorError(ctx, err)
		return
	}
	id, _ := ctx.Get(strings.UserId)
	var user model.User
	user.ID = int32(id.(uint))
	// 查询用户信息
	if err := global.DB.First(&user, user.ID).Error; err != nil {
		zap.S().Errorw("User [ChangePassword] 查询用户失败", "msg", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg: "查询用户失败",
		})
		return
	}
	// 比对原始密码
	if form.OldPassword != user.Password {
		ctx.JSON(http.StatusBadRequest, response.BaseResponse{
			Msg: "原密码不正确",
		})
		return
	}
	// 修改新密码
	user.Password = form.NewPassword
	if err := global.DB.Model(&user).Update("password", user.Password).Error; err != nil {
		zap.S().Errorw("User [ChangePassword] 修改密码失败", "msg", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, response.BaseResponse{
			Msg:  "修改密码失败",
			Data: err,
		})
	}
	ctx.JSON(http.StatusOK, response.BaseResponse{
		Msg: "修改密码成功",
	})
}
